package com.lisp.springframework.core.aop.springaop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class SayHelloAspect {

    @Pointcut(value = "within(com.lisp.springframework.core.aop.springaop..*) && execution(public * sayHello(..)) && args(name,..)", argNames = "name")
    public void sayHello(String name) { }
    
    @Before(value = "sayHello(name)", argNames = "name")
    public void beforeSayHello(String name) {
        System.out.println("before sayHello " + name);
    }
    
    @After(value = "sayHello(name)", argNames = "name")
    public void afterSayHello(String name) {
        System.out.println("after say hello " + name);
    }
    
    @Around(value = "sayHello(name)", argNames = "name")
    public Object aroundSayHello(ProceedingJoinPoint pjp, String name) throws Throwable {
        long current = System.currentTimeMillis();
        Object retVal = pjp.proceed();
        long usedTime = System.currentTimeMillis() - current;
        System.out.println("aroud sayHello advice executed " + usedTime); 
        return retVal;
    }
    
    @Before(value = "within(com.lisp.springframework.core.aop.springaop..*) && execution(public * innerInvoke(..))")
    public void beforeInnerInvoke() {
        System.out.println("------------before innerInvoke--------------");
    }
}
